<template>
    <el-dialog v-model="visible" :title="dialogTitle" width="769px">
        <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="80px">
            <el-form-item label="上级菜单" prop="parentId">
                <el-tree-select
                    v-model="ruleForm.parentId"
                    :data="parentData"
                    check-strictly
                    :render-after-expand="false"
                    placeholder="请选择上级菜单"
                />
            </el-form-item>
            <el-form-item label="菜单类型" prop="name">
                <el-radio-group v-model="ruleForm.type" @change="changeType">
                    <el-radio :value="MenuTypeEnum.CATALOG">目录</el-radio>
                    <el-radio :value="MenuTypeEnum.MENU">菜单</el-radio>
                    <el-radio :value="MenuTypeEnum.EXTLINK">外链</el-radio>
                    <el-radio :value="MenuTypeEnum.BUTTON">按钮</el-radio>
                </el-radio-group>
            </el-form-item>
            <el-form-item label="菜单名称" prop="name">
                <el-input v-model="ruleForm.name" placeholder="请输入菜单名称" clearable />
            </el-form-item>
            <el-form-item v-if="['CATALOG', 'MENU', 'EXTLINK'].includes(ruleForm.type)" label="菜单图标" prop="icon">
                <IconSelector v-model="ruleForm.icon" placeholder="请输入菜单图标" style="width: 100%" />
            </el-form-item>
            <el-form-item v-if="['MENU'].includes(ruleForm.type)" label="组件路径" prop="component">
                <el-input v-model="ruleForm.component" placeholder="请输入组件路径" clearable>
                    <template #prepend>
                        <span>src/views/</span>
                    </template>
                    <template #append>
                        <span>.vue</span>
                    </template>
                </el-input>
            </el-form-item>
            <el-form-item v-if="['MENU', 'CATALOG', 'EXTLINK'].includes(ruleForm.type)" label="路由路径" prop="path">
                <el-input v-model="ruleForm.path" placeholder="请输入路由路径" clearable />
            </el-form-item>
            <el-form-item v-if="['CATALOG'].includes(ruleForm.type)" label="跳转路径" prop="redirect">
                <el-input v-model="ruleForm.redirect" placeholder="请输入跳转路径" clearable />
            </el-form-item>
            <el-form-item v-if="['EXTLINK'].includes(ruleForm.type)" label="外链地址" prop="url">
                <el-input v-model="ruleForm.url" placeholder="请输入外链地址" clearable />
            </el-form-item>
            <el-form-item v-if="['BUTTON', 'MENU'].includes(ruleForm.type)" label="权限标识" prop="perm">
                <el-input v-model="ruleForm.perm" placeholder="请输入权限标识" clearable />
            </el-form-item>
            <el-form-item label="排序" prop="sort">
                <el-input-number v-model="ruleForm.sort" :min="1" style="width: 100%" />
            </el-form-item>
            <el-form-item label="显示状态" prop="visible">
                <el-radio-group v-model="ruleForm.visible">
                    <el-radio :value="1">显示</el-radio>
                    <el-radio :value="0">隐藏</el-radio>
                </el-radio-group>
            </el-form-item>
            <el-form-item v-if="['MENU', 'EXTLINK'].includes(ruleForm.type)" label="页面缓存" prop="keepAlive">
                <el-radio-group v-model="ruleForm.keepAlive">
                    <el-radio :value="1">缓存</el-radio>
                    <el-radio :value="0">不缓存</el-radio>
                </el-radio-group>
            </el-form-item>
        </el-form>
        <template #footer>
            <span class="dialog-footer">
                <el-button size="default" @click="onCancel">取 消</el-button>
                <el-button type="primary" size="default" @click="onSubmit(ruleFormRef)">保 存</el-button>
            </span>
        </template>
    </el-dialog>
</template>
<script lang="ts" setup>
import { ref, reactive } from 'vue'
import { ElMessage } from 'element-plus'
import type { FormInstance, FormRules } from 'element-plus'
import { Menu } from '@/api/system/menu/types.ts'
import { Option } from '@/api/types.ts'
import { getMenuOptions, saveMenu, updateMenu } from '@/api/system/menu/index.ts'
import { resetForm } from '@/utils/index.ts'
import { MenuTypeEnum } from '@/enums/MenuTypeEnum'
import IconSelector from '@/components/IconSelector/index.vue'

const visible = ref(false)
const dialogTitle = ref('新增菜单')
const ruleFormRef = ref<FormInstance>()
/** 定义表单 */
const defaultRuleForm: Menu.Form = {
    sort: 1,
    type: 'MENU',
    visible: 1,
    keepAlive: 1,
}
const ruleForm = reactive<Menu.Form>({
    sort: 1,
    type: 'MENU',
    visible: 1,
    keepAlive: 1,
})
/** 定义表单校验规则 */
const rules = reactive<FormRules<Menu.Form>>({
    name: [{ required: true, message: '请输入菜单名称', trigger: 'blur' }],
    parentId: [{ required: true, message: '请选择顶级菜单', trigger: 'blur' }],
    type: [{ required: true, message: '请选择菜单类型', trigger: 'blur' }],
    path: [{ required: true, message: '请输入路由路径', trigger: 'blur' }],
    component: [{ required: true, message: '请输入组件路径', trigger: 'blur' }],
    visible: [{ required: true, message: '请输入路由路径', trigger: 'blur' }],
})

/**
 * 修改菜单类型
 */
const changeType = () => {
    //菜单
    if (ruleForm.type === MenuTypeEnum.MENU) {
        ruleForm.redirect = ''
        ruleForm.perm = ''
        ruleForm.url = ''
    } else if (ruleForm.type === MenuTypeEnum.CATALOG) {
        ruleForm.keepAlive = 0
        ruleForm.url = ''
        ruleForm.perm = ''
    } else if (ruleForm.type === MenuTypeEnum.BUTTON) {
        ruleForm.keepAlive = 0
        ruleForm.visible = 1
        ruleForm.component = ''
        ruleForm.path = ''
        ruleForm.redirect = ''
        ruleForm.url = ''
        ruleForm.keepAlive = 0
    } else if (ruleForm.type === MenuTypeEnum.EXTLINK) {
        ruleForm.component = ''
        ruleForm.keepAlive = 1
        ruleForm.perm = ''
        ruleForm.redirect = ''
    }
}

/** 关闭弹窗 */
const onCancel = () => {
    visible.value = false
}
/** 打开弹窗 */
const openDialog = (item: Menu.Form) => {
    ruleFormRef.value?.clearValidate()
    if (item) {
        dialogTitle.value = '编辑菜单'
        Object.assign(ruleForm, item)
    } else {
        dialogTitle.value = '新增菜单'
        resetForm(ruleForm, defaultRuleForm)
    }
    getParentList()
    visible.value = true
}

const parentData = reactive<Array<Option>>([
    {
        label: '顶级菜单',
        value: 0,
    },
])
const getParentList = () => {
    getMenuOptions().then((resp) => {
        parentData[0].children = resp
    })
}
// 定义子组件向父组件传值/事件
const emit = defineEmits(['refresh'])
const onSubmit = async (formEl: FormInstance | undefined) => {
    if (!formEl) return
    await formEl.validate((valid) => {
        if (valid) {
            if (ruleForm.id) {
                updateMenu(ruleForm).then(() => {
                    ElMessage.success('保存成功')
                    visible.value = false
                    emit('refresh')
                })
            } else {
                saveMenu(ruleForm).then(() => {
                    ElMessage.success('保存成功')
                    visible.value = false
                    emit('refresh')
                })
            }
        }
    })
}

defineExpose({
    openDialog,
})
</script>
